head(readstate)
multi_cluster <- readstate %>%
  group_by(state,months) %>%
  summarise(` Maximum Temperature`= max(` Maximum Temperature`),
            ` Minimum Temperature`= min(` Minimum Temperature`),
            ` Precipitation` = mean(` Precipitation`), 
            ` Average Temperature` = mean(` Average Temperature`),
            ` Palmer Drought Severity Index (PDSI)`
            )
`summarise()` has grouped output by 'state', 'months'. You can override using
the `.groups` argument.
multi_cluster <- multi_cluster %>%
  group_by(state) %>%
  summarise(max(` Maximum Temperature`), min(` Minimum Temperature`), mean(` Precipitation`)
            , mean(` Average Temperature`), mean(` Palmer Drought Severity Index (PDSI)`))

# ho cercato su internet precipitazioni medie annuali texas -> 51.2 inches -> divido per 12 -> 4.266667
multi_cluster[multi_cluster$state=="Texas",4] <- 4.266667
multi_cluster[multi_cluster$state=="Alaska",6] <- 0
which(is.na(multi_cluster))
integer(0)
  dataset.e <- dist(multi_cluster, method = 'euclidean') #no method -> euclidean (default)
Warning in dist(multi_cluster, method = "euclidean") :
  NAs introduced by coercion
  dataset.es <- hclust(dataset.e, method = 'single') 
  dataset.ea <- hclust(dataset.e, method = 'average')
  dataset.ec <- hclust(dataset.e, method = 'complete')
  dataset.ew <- hclust(dataset.e, method = 'ward.D2')
  
  #plot of dendograms
  par(mfrow=c(1,3))
  plot(dataset.es, main='euclidean-single', hang=-0.1, xlab='', labels=F, cex=0.6, sub='')
  plot(dataset.ec, main='euclidean-complete', hang=-0.1, xlab='', labels=F, cex=0.6, sub='')
  plot(dataset.ea, main='euclidean-average', hang=-0.1, xlab='', labels=F, cex=0.6, sub='')

  plot(dataset.ew, main='euclidean-ward', hang=-0.1, xlab='', labels=F, cex=0.6, sub='')


  
  #cutting dendograms: (with k=2 fixed)
  cluster.ec <- cutree(dataset.ec, k=3) # euclidean-complete:
  cluster.ea <- cutree(dataset.ea, k=3) # euclidean-average:
  cluster.es <- cutree(dataset.es, k=3) # euclidean-simple:
  cluster.ew <- cutree(dataset.ew, k=3) # euclidean-simple:

  
  
  # Let's give a mark to the algorithms: did they aggregate coherently with
  # the dissimilarity matrix or not?
  # compute the cophenetic matrices 
  coph.es <- cophenetic(dataset.es)
  coph.ec <- cophenetic(dataset.ec)
  coph.ea <- cophenetic(dataset.ea)
  coph.ew <- cophenetic(dataset.ew)

  
  # compute cophenetic coefficients (<-> corr(D,C)) D:dist mat; C:coph dist mat
  es <- cor(dataset.e, coph.es)
  ec <- cor(dataset.e, coph.ec)
  ea <- cor(dataset.e, coph.ea)
  ew <- cor(dataset.e, coph.ew)

  
  c("Eucl-Single"=es,"Eucl-Compl."=ec,"Eucl-Ave."=ea, "Eucl-War."=ew)
Eucl-Single Eucl-Compl.   Eucl-Ave.   Eucl-War. 
  0.5302177   0.6771974   0.7414933   0.6742687 

Ha più senso utilizzare Euclidean-Average con k=3

library(plotly)
us_data <- map_data("state")
df <- data.frame(
  state = tolower(multi_cluster$state),
  values = cluster.ew
)

library(usmap)
plot_usmap(data = df) + labs(title = "Multivariate cluster (all cov)")

#Now standardize data

std_multi_cluster<- scale(multi_cluster[,-1])
dataset.e <- dist(std_multi_cluster, method = 'euclidean') #no method -> euclidean (default)

  dataset.es <- hclust(dataset.e, method = 'single') 
  dataset.ea <- hclust(dataset.e, method = 'average')
  dataset.ec <- hclust(dataset.e, method = 'complete')
  dataset.ew <- hclust(dataset.e, method = 'ward.D2')
  
  #plot of dendograms
  par(mfrow=c(1,3))
  plot(dataset.es, main='euclidean-single', hang=-0.1, xlab='', labels=F, cex=0.6, sub='')
  plot(dataset.ec, main='euclidean-complete', hang=-0.1, xlab='', labels=F, cex=0.6, sub='')
  plot(dataset.ea, main='euclidean-average', hang=-0.1, xlab='', labels=F, cex=0.6, sub='')

  plot(dataset.ew, main='euclidean-ward', hang=-0.1, xlab='', labels=F, cex=0.6, sub='')


  
  #cutting dendograms: (with k=2 fixed)
  cluster.ec <- cutree(dataset.ec, k=3) 
  cluster.ea <- cutree(dataset.ea, k=4) # va bene 3 o 4
  cluster.es <- cutree(dataset.es, k=3) 
  cluster.ew <- cutree(dataset.ew, k=4) #va bene 3 o 4

  
  
  # Let's give a mark to the algorithms: did they aggregate coherently with
  # the dissimilarity matrix or not?
  # compute the cophenetic matrices 
  coph.es <- cophenetic(dataset.es)
  coph.ec <- cophenetic(dataset.ec)
  coph.ea <- cophenetic(dataset.ea)
  coph.ew <- cophenetic(dataset.ew)

  
  # compute cophenetic coefficients (<-> corr(D,C)) D:dist mat; C:coph dist mat
  es <- cor(dataset.e, coph.es)
  ec <- cor(dataset.e, coph.ec)
  ea <- cor(dataset.e, coph.ea)
  ew <- cor(dataset.e, coph.ew)

  
  c("Eucl-Single"=es,"Eucl-Compl."=ec,"Eucl-Ave."=ea, "Eucl-War."=ew)
Eucl-Single Eucl-Compl.   Eucl-Ave.   Eucl-War. 
  0.6070141   0.7259835   0.7478126   0.5723762 

Anche in questo caso E-A ma k=2 migliore (ignoreremo ciò e usiamo k=3)

library(plotly)
us_data <- map_data("state")
df <- data.frame(
  state = tolower(multi_cluster$state),
  values = cluster.ew
)

library(usmap)
plot_usmap(data = df) + labs(title = "Std Multivariate cluster (all cov)")

CLUSTER SENZA PDSI

std_multi_cluster<- scale(multi_cluster[,-c(1,6)])
dataset.e <- dist(std_multi_cluster, method = 'euclidean') #no method -> euclidean (default)

  dataset.es <- hclust(dataset.e, method = 'single') 
  dataset.ea <- hclust(dataset.e, method = 'average')
  dataset.ec <- hclust(dataset.e, method = 'complete')
  dataset.ew <- hclust(dataset.e, method = 'ward.D2')
  
  #plot of dendograms
  par(mfrow=c(1,3))
  plot(dataset.es, main='euclidean-single', hang=-0.1, xlab='', labels=F, cex=0.6, sub='')
  plot(dataset.ec, main='euclidean-complete', hang=-0.1, xlab='', labels=F, cex=0.6, sub='')
  plot(dataset.ea, main='euclidean-average', hang=-0.1, xlab='', labels=F, cex=0.6, sub='')

  plot(dataset.ew, main='euclidean-ward', hang=-0.1, xlab='', labels=F, cex=0.6, sub='')


  
  #cutting dendograms: (with k=2 fixed)
  cluster.ec <- cutree(dataset.ec, k=3) # euclidean-complete:
  cluster.ea <- cutree(dataset.ea, k=3) # euclidean-average:
  cluster.es <- cutree(dataset.es, k=3) # euclidean-simple:
  cluster.ew <- cutree(dataset.ew, k=4) # euclidean-simple:

  
  
  # Let's give a mark to the algorithms: did they aggregate coherently with
  # the dissimilarity matrix or not?
  # compute the cophenetic matrices 
  coph.es <- cophenetic(dataset.es)
  coph.ec <- cophenetic(dataset.ec)
  coph.ea <- cophenetic(dataset.ea)
  coph.ew <- cophenetic(dataset.ew)

  
  # compute cophenetic coefficients (<-> corr(D,C)) D:dist mat; C:coph dist mat
  es <- cor(dataset.e, coph.es)
  ec <- cor(dataset.e, coph.ec)
  ea <- cor(dataset.e, coph.ea)
  ew <- cor(dataset.e, coph.ew)

  
  c("Eucl-Single"=es,"Eucl-Compl."=ec,"Eucl-Ave."=ea, "Eucl-War."=ew)
Eucl-Single Eucl-Compl.   Eucl-Ave.   Eucl-War. 
  0.5942218   0.5589432   0.7714117   0.5725603 
library(plotly)
us_data <- map_data("state")
df <- data.frame(
  state = tolower(multi_cluster$state),
  values = cluster.ew
)

library(usmap)
plot_usmap(data = df) + labs(title = "Std Multivariate cluster (without PDSI)")

plot_ly(x=std_multi_cluster[,1], y=std_multi_cluster[,2], z=std_multi_cluster[,3], color=cluster.ew, pch=19)
No trace type specified:
  Based on info supplied, a 'scatter3d' trace seems appropriate.
  Read more about this trace type -> https://plotly.com/r/reference/#scatter3d
No scatter3d mode specifed:
  Setting the mode to markers
  Read more about this attribute -> https://plotly.com/r/reference/#scatter-mode
Warning: 'scatter3d' objects don't have these attributes: 'pch'
Valid attributes include:
'connectgaps', 'customdata', 'customdatasrc', 'error_x', 'error_y', 'error_z', 'hoverinfo', 'hoverinfosrc', 'hoverlabel', 'hovertemplate', 'hovertemplatesrc', 'hovertext', 'hovertextsrc', 'ids', 'idssrc', 'legendgroup', 'legendgrouptitle', 'legendrank', 'line', 'marker', 'meta', 'metasrc', 'mode', 'name', 'opacity', 'projection', 'scene', 'showlegend', 'stream', 'surfaceaxis', 'surfacecolor', 'text', 'textfont', 'textposition', 'textpositionsrc', 'textsrc', 'texttemplate', 'texttemplatesrc', 'transforms', 'type', 'uid', 'uirevision', 'visible', 'x', 'xcalendar', 'xhoverformat', 'xsrc', 'y', 'ycalendar', 'yhoverformat', 'ysrc', 'z', 'zcalendar', 'zhoverformat', 'zsrc', 'key', 'set', 'frame', 'transforms', '_isNestedKey', '_isSimpleKey', '_isGraticule', '_bbox'

No trace type specified:
  Based on info supplied, a 'scatter3d' trace seems appropriate.
  Read more about this trace type -> https://plotly.com/r/reference/#scatter3d
No scatter3d mode specifed:
  Setting the mode to markers
  Read more about this attribute -> https://plotly.com/r/reference/#scatter-mode
Warning: 'scatter3d' objects don't have these attributes: 'pch'
Valid attributes include:
'connectgaps', 'customdata', 'customdatasrc', 'error_x', 'error_y', 'error_z', 'hoverinfo', 'hoverinfosrc', 'hoverlabel', 'hovertemplate', 'hovertemplatesrc', 'hovertext', 'hovertextsrc', 'ids', 'idssrc', 'legendgroup', 'legendgrouptitle', 'legendrank', 'line', 'marker', 'meta', 'metasrc', 'mode', 'name', 'opacity', 'projection', 'scene', 'showlegend', 'stream', 'surfaceaxis', 'surfacecolor', 'text', 'textfont', 'textposition', 'textpositionsrc', 'textsrc', 'texttemplate', 'texttemplatesrc', 'transforms', 'type', 'uid', 'uirevision', 'visible', 'x', 'xcalendar', 'xhoverformat', 'xsrc', 'y', 'ycalendar', 'yhoverformat', 'ysrc', 'z', 'zcalendar', 'zhoverformat', 'zsrc', 'key', 'set', 'frame', 'transforms', '_isNestedKey', '_isSimpleKey', '_isGraticule', '_bbox'
LS0tDQp0aXRsZTogIkFtYmllbnRhbCBjbHVzdGVyIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KDQoNCmBgYHtyfQ0KaGVhZChyZWFkc3RhdGUpDQptdWx0aV9jbHVzdGVyIDwtIHJlYWRzdGF0ZSAlPiUNCiAgZ3JvdXBfYnkoc3RhdGUsbW9udGhzKSAlPiUNCiAgc3VtbWFyaXNlKGAgTWF4aW11bSBUZW1wZXJhdHVyZWA9IG1heChgIE1heGltdW0gVGVtcGVyYXR1cmVgKSwNCiAgICAgICAgICAgIGAgTWluaW11bSBUZW1wZXJhdHVyZWA9IG1pbihgIE1pbmltdW0gVGVtcGVyYXR1cmVgKSwNCiAgICAgICAgICAgIGAgUHJlY2lwaXRhdGlvbmAgPSBtZWFuKGAgUHJlY2lwaXRhdGlvbmApLCANCiAgICAgICAgICAgIGAgQXZlcmFnZSBUZW1wZXJhdHVyZWAgPSBtZWFuKGAgQXZlcmFnZSBUZW1wZXJhdHVyZWApLA0KICAgICAgICAgICAgYCBQYWxtZXIgRHJvdWdodCBTZXZlcml0eSBJbmRleCAoUERTSSlgDQogICAgICAgICAgICApDQoNCm11bHRpX2NsdXN0ZXIgPC0gbXVsdGlfY2x1c3RlciAlPiUNCiAgZ3JvdXBfYnkoc3RhdGUpICU+JQ0KICBzdW1tYXJpc2UobWF4KGAgTWF4aW11bSBUZW1wZXJhdHVyZWApLCBtaW4oYCBNaW5pbXVtIFRlbXBlcmF0dXJlYCksIG1lYW4oYCBQcmVjaXBpdGF0aW9uYCkNCiAgICAgICAgICAgICwgbWVhbihgIEF2ZXJhZ2UgVGVtcGVyYXR1cmVgKSwgbWVhbihgIFBhbG1lciBEcm91Z2h0IFNldmVyaXR5IEluZGV4IChQRFNJKWApKQ0KDQojIGhvIGNlcmNhdG8gc3UgaW50ZXJuZXQgcHJlY2lwaXRhemlvbmkgbWVkaWUgYW5udWFsaSB0ZXhhcyAtPiA1MS4yIGluY2hlcyAtPiBkaXZpZG8gcGVyIDEyIC0+IDQuMjY2NjY3DQptdWx0aV9jbHVzdGVyW211bHRpX2NsdXN0ZXIkc3RhdGU9PSJUZXhhcyIsNF0gPC0gNC4yNjY2NjcNCm11bHRpX2NsdXN0ZXJbbXVsdGlfY2x1c3RlciRzdGF0ZT09IkFsYXNrYSIsNl0gPC0gMA0Kd2hpY2goaXMubmEobXVsdGlfY2x1c3RlcikpDQpgYGANCmBgYHtyfQ0KICBkYXRhc2V0LmUgPC0gZGlzdChtdWx0aV9jbHVzdGVyLCBtZXRob2QgPSAnZXVjbGlkZWFuJykgI25vIG1ldGhvZCAtPiBldWNsaWRlYW4gKGRlZmF1bHQpDQoNCiAgZGF0YXNldC5lcyA8LSBoY2x1c3QoZGF0YXNldC5lLCBtZXRob2QgPSAnc2luZ2xlJykgDQogIGRhdGFzZXQuZWEgPC0gaGNsdXN0KGRhdGFzZXQuZSwgbWV0aG9kID0gJ2F2ZXJhZ2UnKQ0KICBkYXRhc2V0LmVjIDwtIGhjbHVzdChkYXRhc2V0LmUsIG1ldGhvZCA9ICdjb21wbGV0ZScpDQogIGRhdGFzZXQuZXcgPC0gaGNsdXN0KGRhdGFzZXQuZSwgbWV0aG9kID0gJ3dhcmQuRDInKQ0KICANCiAgI3Bsb3Qgb2YgZGVuZG9ncmFtcw0KICBwYXIobWZyb3c9YygxLDMpKQ0KICBwbG90KGRhdGFzZXQuZXMsIG1haW49J2V1Y2xpZGVhbi1zaW5nbGUnLCBoYW5nPS0wLjEsIHhsYWI9JycsIGxhYmVscz1GLCBjZXg9MC42LCBzdWI9JycpDQogIHBsb3QoZGF0YXNldC5lYywgbWFpbj0nZXVjbGlkZWFuLWNvbXBsZXRlJywgaGFuZz0tMC4xLCB4bGFiPScnLCBsYWJlbHM9RiwgY2V4PTAuNiwgc3ViPScnKQ0KICBwbG90KGRhdGFzZXQuZWEsIG1haW49J2V1Y2xpZGVhbi1hdmVyYWdlJywgaGFuZz0tMC4xLCB4bGFiPScnLCBsYWJlbHM9RiwgY2V4PTAuNiwgc3ViPScnKQ0KICBwbG90KGRhdGFzZXQuZXcsIG1haW49J2V1Y2xpZGVhbi13YXJkJywgaGFuZz0tMC4xLCB4bGFiPScnLCBsYWJlbHM9RiwgY2V4PTAuNiwgc3ViPScnKQ0KDQogIA0KICAjY3V0dGluZyBkZW5kb2dyYW1zOiAod2l0aCBrPTIgZml4ZWQpDQogIGNsdXN0ZXIuZWMgPC0gY3V0cmVlKGRhdGFzZXQuZWMsIGs9MykgIyBldWNsaWRlYW4tY29tcGxldGU6DQogIGNsdXN0ZXIuZWEgPC0gY3V0cmVlKGRhdGFzZXQuZWEsIGs9MykgIyBldWNsaWRlYW4tYXZlcmFnZToNCiAgY2x1c3Rlci5lcyA8LSBjdXRyZWUoZGF0YXNldC5lcywgaz0zKSAjIGV1Y2xpZGVhbi1zaW1wbGU6DQogIGNsdXN0ZXIuZXcgPC0gY3V0cmVlKGRhdGFzZXQuZXcsIGs9MykgIyBldWNsaWRlYW4tc2ltcGxlOg0KDQogIA0KICANCiAgIyBMZXQncyBnaXZlIGEgbWFyayB0byB0aGUgYWxnb3JpdGhtczogZGlkIHRoZXkgYWdncmVnYXRlIGNvaGVyZW50bHkgd2l0aA0KICAjIHRoZSBkaXNzaW1pbGFyaXR5IG1hdHJpeCBvciBub3Q/DQogICMgY29tcHV0ZSB0aGUgY29waGVuZXRpYyBtYXRyaWNlcyANCiAgY29waC5lcyA8LSBjb3BoZW5ldGljKGRhdGFzZXQuZXMpDQogIGNvcGguZWMgPC0gY29waGVuZXRpYyhkYXRhc2V0LmVjKQ0KICBjb3BoLmVhIDwtIGNvcGhlbmV0aWMoZGF0YXNldC5lYSkNCiAgY29waC5ldyA8LSBjb3BoZW5ldGljKGRhdGFzZXQuZXcpDQoNCiAgDQogICMgY29tcHV0ZSBjb3BoZW5ldGljIGNvZWZmaWNpZW50cyAoPC0+IGNvcnIoRCxDKSkgRDpkaXN0IG1hdDsgQzpjb3BoIGRpc3QgbWF0DQogIGVzIDwtIGNvcihkYXRhc2V0LmUsIGNvcGguZXMpDQogIGVjIDwtIGNvcihkYXRhc2V0LmUsIGNvcGguZWMpDQogIGVhIDwtIGNvcihkYXRhc2V0LmUsIGNvcGguZWEpDQogIGV3IDwtIGNvcihkYXRhc2V0LmUsIGNvcGguZXcpDQoNCiAgDQogIGMoIkV1Y2wtU2luZ2xlIj1lcywiRXVjbC1Db21wbC4iPWVjLCJFdWNsLUF2ZS4iPWVhLCAiRXVjbC1XYXIuIj1ldykNCg0KYGBgDQpIYSBwacO5IHNlbnNvIHV0aWxpenphcmUgRXVjbGlkZWFuLUF2ZXJhZ2UgY29uIGs9Mw0KDQpgYGB7cn0NCmxpYnJhcnkocGxvdGx5KQ0KdXNfZGF0YSA8LSBtYXBfZGF0YSgic3RhdGUiKQ0KZGYgPC0gZGF0YS5mcmFtZSgNCiAgc3RhdGUgPSB0b2xvd2VyKG11bHRpX2NsdXN0ZXIkc3RhdGUpLA0KICB2YWx1ZXMgPSBjbHVzdGVyLmV3DQopDQoNCmxpYnJhcnkodXNtYXApDQpwbG90X3VzbWFwKGRhdGEgPSBkZikgKyBsYWJzKHRpdGxlID0gIk11bHRpdmFyaWF0ZSBjbHVzdGVyIChhbGwgY292KSIpDQoNCmBgYA0KDQojTm93IHN0YW5kYXJkaXplIGRhdGENCmBgYHtyfQ0Kc3RkX211bHRpX2NsdXN0ZXI8LSBzY2FsZShtdWx0aV9jbHVzdGVyWywtMV0pDQpkYXRhc2V0LmUgPC0gZGlzdChzdGRfbXVsdGlfY2x1c3RlciwgbWV0aG9kID0gJ2V1Y2xpZGVhbicpICNubyBtZXRob2QgLT4gZXVjbGlkZWFuIChkZWZhdWx0KQ0KDQogIGRhdGFzZXQuZXMgPC0gaGNsdXN0KGRhdGFzZXQuZSwgbWV0aG9kID0gJ3NpbmdsZScpIA0KICBkYXRhc2V0LmVhIDwtIGhjbHVzdChkYXRhc2V0LmUsIG1ldGhvZCA9ICdhdmVyYWdlJykNCiAgZGF0YXNldC5lYyA8LSBoY2x1c3QoZGF0YXNldC5lLCBtZXRob2QgPSAnY29tcGxldGUnKQ0KICBkYXRhc2V0LmV3IDwtIGhjbHVzdChkYXRhc2V0LmUsIG1ldGhvZCA9ICd3YXJkLkQyJykNCiAgDQogICNwbG90IG9mIGRlbmRvZ3JhbXMNCiAgcGFyKG1mcm93PWMoMSwzKSkNCiAgcGxvdChkYXRhc2V0LmVzLCBtYWluPSdldWNsaWRlYW4tc2luZ2xlJywgaGFuZz0tMC4xLCB4bGFiPScnLCBsYWJlbHM9RiwgY2V4PTAuNiwgc3ViPScnKQ0KICBwbG90KGRhdGFzZXQuZWMsIG1haW49J2V1Y2xpZGVhbi1jb21wbGV0ZScsIGhhbmc9LTAuMSwgeGxhYj0nJywgbGFiZWxzPUYsIGNleD0wLjYsIHN1Yj0nJykNCiAgcGxvdChkYXRhc2V0LmVhLCBtYWluPSdldWNsaWRlYW4tYXZlcmFnZScsIGhhbmc9LTAuMSwgeGxhYj0nJywgbGFiZWxzPUYsIGNleD0wLjYsIHN1Yj0nJykNCiAgcGxvdChkYXRhc2V0LmV3LCBtYWluPSdldWNsaWRlYW4td2FyZCcsIGhhbmc9LTAuMSwgeGxhYj0nJywgbGFiZWxzPUYsIGNleD0wLjYsIHN1Yj0nJykNCg0KICANCiAgI2N1dHRpbmcgZGVuZG9ncmFtczogKHdpdGggaz0yIGZpeGVkKQ0KICBjbHVzdGVyLmVjIDwtIGN1dHJlZShkYXRhc2V0LmVjLCBrPTMpIA0KICBjbHVzdGVyLmVhIDwtIGN1dHJlZShkYXRhc2V0LmVhLCBrPTQpICMgdmEgYmVuZSAzIG8gNA0KICBjbHVzdGVyLmVzIDwtIGN1dHJlZShkYXRhc2V0LmVzLCBrPTMpIA0KICBjbHVzdGVyLmV3IDwtIGN1dHJlZShkYXRhc2V0LmV3LCBrPTQpICN2YSBiZW5lIDMgbyA0DQoNCiAgDQogIA0KICAjIExldCdzIGdpdmUgYSBtYXJrIHRvIHRoZSBhbGdvcml0aG1zOiBkaWQgdGhleSBhZ2dyZWdhdGUgY29oZXJlbnRseSB3aXRoDQogICMgdGhlIGRpc3NpbWlsYXJpdHkgbWF0cml4IG9yIG5vdD8NCiAgIyBjb21wdXRlIHRoZSBjb3BoZW5ldGljIG1hdHJpY2VzIA0KICBjb3BoLmVzIDwtIGNvcGhlbmV0aWMoZGF0YXNldC5lcykNCiAgY29waC5lYyA8LSBjb3BoZW5ldGljKGRhdGFzZXQuZWMpDQogIGNvcGguZWEgPC0gY29waGVuZXRpYyhkYXRhc2V0LmVhKQ0KICBjb3BoLmV3IDwtIGNvcGhlbmV0aWMoZGF0YXNldC5ldykNCg0KICANCiAgIyBjb21wdXRlIGNvcGhlbmV0aWMgY29lZmZpY2llbnRzICg8LT4gY29ycihELEMpKSBEOmRpc3QgbWF0OyBDOmNvcGggZGlzdCBtYXQNCiAgZXMgPC0gY29yKGRhdGFzZXQuZSwgY29waC5lcykNCiAgZWMgPC0gY29yKGRhdGFzZXQuZSwgY29waC5lYykNCiAgZWEgPC0gY29yKGRhdGFzZXQuZSwgY29waC5lYSkNCiAgZXcgPC0gY29yKGRhdGFzZXQuZSwgY29waC5ldykNCg0KICANCiAgYygiRXVjbC1TaW5nbGUiPWVzLCJFdWNsLUNvbXBsLiI9ZWMsIkV1Y2wtQXZlLiI9ZWEsICJFdWNsLVdhci4iPWV3KQ0KYGBgDQpBbmNoZSBpbiBxdWVzdG8gY2FzbyBFLUEgbWEgaz0yIG1pZ2xpb3JlIChpZ25vcmVyZW1vIGNpw7IgZSB1c2lhbW8gaz0zKQ0KYGBge3J9DQpsaWJyYXJ5KHBsb3RseSkNCnVzX2RhdGEgPC0gbWFwX2RhdGEoInN0YXRlIikNCmRmIDwtIGRhdGEuZnJhbWUoDQogIHN0YXRlID0gdG9sb3dlcihtdWx0aV9jbHVzdGVyJHN0YXRlKSwNCiAgdmFsdWVzID0gY2x1c3Rlci5ldw0KKQ0KDQpsaWJyYXJ5KHVzbWFwKQ0KcGxvdF91c21hcChkYXRhID0gZGYpICsgbGFicyh0aXRsZSA9ICJTdGQgTXVsdGl2YXJpYXRlIGNsdXN0ZXIgKGFsbCBjb3YpIikNCmBgYA0KDQojIyBDTFVTVEVSIFNFTlpBIFBEU0kNCmBgYHtyfQ0Kc3RkX211bHRpX2NsdXN0ZXI8LSBzY2FsZShtdWx0aV9jbHVzdGVyWywtYygxLDYpXSkNCmRhdGFzZXQuZSA8LSBkaXN0KHN0ZF9tdWx0aV9jbHVzdGVyLCBtZXRob2QgPSAnZXVjbGlkZWFuJykgI25vIG1ldGhvZCAtPiBldWNsaWRlYW4gKGRlZmF1bHQpDQoNCiAgZGF0YXNldC5lcyA8LSBoY2x1c3QoZGF0YXNldC5lLCBtZXRob2QgPSAnc2luZ2xlJykgDQogIGRhdGFzZXQuZWEgPC0gaGNsdXN0KGRhdGFzZXQuZSwgbWV0aG9kID0gJ2F2ZXJhZ2UnKQ0KICBkYXRhc2V0LmVjIDwtIGhjbHVzdChkYXRhc2V0LmUsIG1ldGhvZCA9ICdjb21wbGV0ZScpDQogIGRhdGFzZXQuZXcgPC0gaGNsdXN0KGRhdGFzZXQuZSwgbWV0aG9kID0gJ3dhcmQuRDInKQ0KICANCiAgI3Bsb3Qgb2YgZGVuZG9ncmFtcw0KICBwYXIobWZyb3c9YygxLDMpKQ0KICBwbG90KGRhdGFzZXQuZXMsIG1haW49J2V1Y2xpZGVhbi1zaW5nbGUnLCBoYW5nPS0wLjEsIHhsYWI9JycsIGxhYmVscz1GLCBjZXg9MC42LCBzdWI9JycpDQogIHBsb3QoZGF0YXNldC5lYywgbWFpbj0nZXVjbGlkZWFuLWNvbXBsZXRlJywgaGFuZz0tMC4xLCB4bGFiPScnLCBsYWJlbHM9RiwgY2V4PTAuNiwgc3ViPScnKQ0KICBwbG90KGRhdGFzZXQuZWEsIG1haW49J2V1Y2xpZGVhbi1hdmVyYWdlJywgaGFuZz0tMC4xLCB4bGFiPScnLCBsYWJlbHM9RiwgY2V4PTAuNiwgc3ViPScnKQ0KICBwbG90KGRhdGFzZXQuZXcsIG1haW49J2V1Y2xpZGVhbi13YXJkJywgaGFuZz0tMC4xLCB4bGFiPScnLCBsYWJlbHM9RiwgY2V4PTAuNiwgc3ViPScnKQ0KDQogIA0KICAjY3V0dGluZyBkZW5kb2dyYW1zOiAod2l0aCBrPTIgZml4ZWQpDQogIGNsdXN0ZXIuZWMgPC0gY3V0cmVlKGRhdGFzZXQuZWMsIGs9MykgIyBldWNsaWRlYW4tY29tcGxldGU6DQogIGNsdXN0ZXIuZWEgPC0gY3V0cmVlKGRhdGFzZXQuZWEsIGs9MykgIyBldWNsaWRlYW4tYXZlcmFnZToNCiAgY2x1c3Rlci5lcyA8LSBjdXRyZWUoZGF0YXNldC5lcywgaz0zKSAjIGV1Y2xpZGVhbi1zaW1wbGU6DQogIGNsdXN0ZXIuZXcgPC0gY3V0cmVlKGRhdGFzZXQuZXcsIGs9NCkgIyBldWNsaWRlYW4tc2ltcGxlOg0KDQogIA0KICANCiAgIyBMZXQncyBnaXZlIGEgbWFyayB0byB0aGUgYWxnb3JpdGhtczogZGlkIHRoZXkgYWdncmVnYXRlIGNvaGVyZW50bHkgd2l0aA0KICAjIHRoZSBkaXNzaW1pbGFyaXR5IG1hdHJpeCBvciBub3Q/DQogICMgY29tcHV0ZSB0aGUgY29waGVuZXRpYyBtYXRyaWNlcyANCiAgY29waC5lcyA8LSBjb3BoZW5ldGljKGRhdGFzZXQuZXMpDQogIGNvcGguZWMgPC0gY29waGVuZXRpYyhkYXRhc2V0LmVjKQ0KICBjb3BoLmVhIDwtIGNvcGhlbmV0aWMoZGF0YXNldC5lYSkNCiAgY29waC5ldyA8LSBjb3BoZW5ldGljKGRhdGFzZXQuZXcpDQoNCiAgDQogICMgY29tcHV0ZSBjb3BoZW5ldGljIGNvZWZmaWNpZW50cyAoPC0+IGNvcnIoRCxDKSkgRDpkaXN0IG1hdDsgQzpjb3BoIGRpc3QgbWF0DQogIGVzIDwtIGNvcihkYXRhc2V0LmUsIGNvcGguZXMpDQogIGVjIDwtIGNvcihkYXRhc2V0LmUsIGNvcGguZWMpDQogIGVhIDwtIGNvcihkYXRhc2V0LmUsIGNvcGguZWEpDQogIGV3IDwtIGNvcihkYXRhc2V0LmUsIGNvcGguZXcpDQoNCiAgDQogIGMoIkV1Y2wtU2luZ2xlIj1lcywiRXVjbC1Db21wbC4iPWVjLCJFdWNsLUF2ZS4iPWVhLCAiRXVjbC1XYXIuIj1ldykNCmBgYA0KYGBge3J9DQpsaWJyYXJ5KHBsb3RseSkNCnVzX2RhdGEgPC0gbWFwX2RhdGEoInN0YXRlIikNCmRmIDwtIGRhdGEuZnJhbWUoDQogIHN0YXRlID0gdG9sb3dlcihtdWx0aV9jbHVzdGVyJHN0YXRlKSwNCiAgdmFsdWVzID0gY2x1c3Rlci5ldw0KKQ0KDQpsaWJyYXJ5KHVzbWFwKQ0KcGxvdF91c21hcChkYXRhID0gZGYpICsgbGFicyh0aXRsZSA9ICJTdGQgTXVsdGl2YXJpYXRlIGNsdXN0ZXIgKHdpdGhvdXQgUERTSSkiKQ0KYGBgDQoNCmBgYHtyfQ0KcGxvdF9seSh4PXN0ZF9tdWx0aV9jbHVzdGVyWywxXSwgeT1zdGRfbXVsdGlfY2x1c3RlclssMl0sIHo9c3RkX211bHRpX2NsdXN0ZXJbLDNdLCBjb2xvcj1jbHVzdGVyLmV3LCBwY2g9MTkpDQpgYGANCg0K